package com.spring.framework.transaction.listener;

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * 测试中，执行业务方法和执行事件方法的线程是同一个，不行的话可以测试一下！
 *
 * 加上线程信息，并且假设它们每一个方法执行需要一秒钟时间,很明显，无论是执行service业务方法，还是执行事件方法，都是同一个main线程搞定的，
 * 业务方法返回耗费了超过4秒。实际上Spring提供的事件通知机制默认情况下都是同步事件，即谁发出的事件，谁就去处理事件！
 */
@Async
@Component
@SuppressWarnings("all")
public class MyTransactionalEventListener {

	/**
	 * 事件回滚后监听器
	 *
	 * @param str 发布的事件，要求是String及其兼容类型
	 */
	@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK, fallbackExecution = true)
	public void afterRollback(String str) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----AFTER_ROLLBACK: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("AFTER_ROLLBACK: " + str);
	}

	/**
	 * 事件提交前监听器
	 *
	 * @param str 发布的事件，要求是String及其兼容类型
	 */
	@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT, fallbackExecution = true)
	public void beforeCommit(String str) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----BEFORE_COMMIT: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("BEFORE_COMMIT: " + str);
	}

	/**
	 * 事件提交后监听器
	 *
	 * @param str 发布的事件，要求是String及其兼容类型
	 */
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
	public void afterCommit(String str) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----AFTER_COMMIT: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("AFTER_COMMIT: " + str);
	}

	/**
	 * 事件完成后监听器
	 *
	 * @param str 发布的事件，要求是String及其兼容类型
	 */
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION, fallbackExecution = true)
	public void afterCompletion(String str) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----AFTER_COMPLETION: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("AFTER_COMPLETION: " + str);
	}

	//普通事件监听器

	/**
	 * 普通事件监听器
	 *
	 * @param str 发布的事件，要求是String及其兼容类型
	 */
	@EventListener
	public void listen(String str) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----普通事件 String: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("普通事件: " + str);
	}

	/**
	 * 普通事件监听器
	 *
	 * @param integer 发布的事件，要求是Integer及其兼容类型
	 */
	@EventListener
	public void listen(Integer integer) {
		//假设需要一秒钟处理时间
		LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
		System.out.println("-----AFTER_ROLLBACK: " + Thread.currentThread().getName());
		//获取事件传递的数据
		System.out.println("普通事件 Integer: " + integer);
	}
}

